package cn.dgiot.fd.service.impl;

import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import cn.dgiot.fd.service.IDeviceStateService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.common.utils.StringUtils;

import cn.dgiot.fd.contant.AliyunConfig;
import cn.dgiot.fd.contant.CustomTopicEnum;
import cn.dgiot.fd.contant.DeviceStateEnum;
import cn.dgiot.fd.contant.ReportPropertyTypeEnum;
import cn.dgiot.fd.model.DevicePLC;
import cn.dgiot.fd.model.DeviceStateModel;
import cn.dgiot.fd.model.DeviceUpgradeFlowModel;
import cn.dgiot.fd.model.DeviceUpgradeModel;
import cn.dgiot.fd.model.DictionarieModel;
import cn.dgiot.fd.model.PLCModelFlow;
import cn.dgiot.fd.model.PLCWarnFlowModel;
import cn.dgiot.fd.model.PLCWarnModel;
import cn.dgiot.fd.model.PLCWarnReportModel;
import cn.dgiot.fd.model.PropertiesSetFlowModel;
import cn.dgiot.fd.model.PropertiesSetModel;
import cn.dgiot.fd.model.PropertyReportFlowModel;
import cn.dgiot.fd.model.PropertyReportModel;
import cn.dgiot.fd.service.IAmqpMessageHandler;
import cn.dgiot.fd.service.IDevicePLCService;
import cn.dgiot.fd.service.IDeviceUpgradeFlowService;
import cn.dgiot.fd.service.IDeviceUpgradeService;
import cn.dgiot.fd.service.IDictionarieService;
import cn.dgiot.fd.service.IPLCModelFlowService;
import cn.dgiot.fd.service.IPLCWarnFlowService;
import cn.dgiot.fd.service.IPLCWarnReportService;
import cn.dgiot.fd.service.IPLCWarnService;
import cn.dgiot.fd.service.IPropertiesSetFlowService;
import cn.dgiot.fd.service.IPropertiesSetService;
import cn.dgiot.fd.service.IPropertyReportFlowService;
import cn.dgiot.fd.service.IPropertyReportService;
import cn.dgiot.fd.utils.Calculator;
import cn.dgiot.fd.utils.DateUtil;

/**
 * [amqp消息处理]
 * 
 * @author
 *
 */
@Service
public class AmqpMessageHandlerImpl implements IAmqpMessageHandler {

	@Autowired
	private AliyunConfig aliyunConfig;

	@Autowired
	private IDictionarieService dictionarieService;

	@Autowired
	private IDeviceStateService deviceStateService;

	@Autowired
	private IDeviceUpgradeService deviceUpgradeService;

	@Autowired
	private IDeviceUpgradeFlowService deviceUpgradeFlowService;

	@Autowired
	private IPLCWarnService plcWarnService;

	@Autowired
	private IPLCWarnFlowService plcWarnFlowService;
	
	@Autowired
	private IPLCWarnReportService plcWarnReportService;

	@Autowired
	private IDevicePLCService devicePLCService;

	@Autowired
	private IPLCModelFlowService plcModelFlowService;
	
	@Autowired
	private IPropertiesSetService propertiesSetService;

	@Autowired
	private IPropertiesSetFlowService propertiesSetFlowService;

	@Autowired
	private IPropertyReportFlowService propertyReportFlowService;

	@Autowired
	private IPropertyReportService propertyReportService;

	private final Logger logger = LoggerFactory.getLogger(AmqpMessageHandlerImpl.class);

	/**
	 * [在线状态]
	 * 
	 * @param topic
	 * @param content
	 * @return
	 */
	private boolean deviceOnline(String topic, String content) {
		boolean flag = false;
		Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
		String status = String.valueOf(json.get("status"));
		if (topic.indexOf(aliyunConfig.statusTopic) >= 0 && "online".equals(status)) {
			flag = true;
		}
		return flag;
	}

	/**
	 * [离线状态]
	 * 
	 * @param topic
	 * @param content
	 * @return
	 */
	private boolean deviceOffline(String topic, String content) {
		boolean flag = false;
		Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
		String status = String.valueOf(json.get("status"));
		if (topic.indexOf(aliyunConfig.statusTopic) >= 0 && "offline".equals(status)) {
			flag = true;
		}
		return flag;
	}

	/**
	 * [设备信息上报]
	 * 
	 * @param topic
	 * @return
	 */
	private boolean devicePropertyPost(String topic) {
		boolean flag = false;
		if (topic.lastIndexOf(aliyunConfig.devicePropertyPostTopic) >= 0) {
			flag = true;
		}
		return flag;
	}

	/**
	 * [自定义topic]
	 * 
	 * @param topic
	 * @return
	 */
	private boolean customTopic(String topic) {
		boolean flag = false;
		if (topic.lastIndexOf(aliyunConfig.customTopic) >= 0) {
			flag = true;
		}
		return flag;
	}

	@Override
	public void processMessage(String topic, String content) {

		Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
		boolean flag = checkDevice(json);
		if(flag) {
			if (devicePropertyPost(topic)) {
				// 设备属性上报
				devicePropertyPostHandler(topic, content);
			} else if (deviceOnline(topic, content)) {
				// 设备上线
				deviceOnlineHandler(topic, content);
			} else if (deviceOffline(topic, content)) {
				// 设备下线
				deviceOfflineHandler(topic, content);
			} else if (dtuOta(topic)) {
				// ota升级反馈
				dtuOtaHandler(topic, content);
			} else if (customTopic(topic)) {
				// 自定义消息处理
				customTopicHandler(topic, content);
			}
		}
	}

	/**
	 * [设备上线]
	 * @param topic
	 * @param content
	 */
	private void deviceOnlineHandler(String topic, String content) {
		Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
		String productKey = String.valueOf(json.get("productKey"));
		String deviceName = String.valueOf(json.get("deviceName"));
		String time = String.valueOf(json.get("time"));
		DeviceStateModel deviceStateModel = new DeviceStateModel();
		deviceStateModel.setProductKey(productKey);
		deviceStateModel.setDeviceName(deviceName);
		DeviceStateModel result = deviceStateService.getDeviceState(deviceStateModel);
		if(result != null) {
			Timestamp updateTime = result.getUpdateTime();
			Timestamp resultTime = new Timestamp(DateUtil.parseDate(time,"yyyy-MM-dd HH:mm:ss").getTime());
			if(updateTime == null || resultTime == null ||
					updateTime.before(resultTime)) {
				deviceStateModel.setState(DeviceStateEnum.ON_LINE.getCode());
				deviceStateModel.setUpdateTime(resultTime);
				deviceStateService.updateDeviceState(deviceStateModel);
			}else {
				logger.info("-------本次设备状态更新时间:"+resultTime+",上次设备状态更新时间:\"+updateTime+\",不需要做状态更新--------------------");
			}
		}
	}

	/**
	 * [设备下线]
	 * @param topic
	 * @param content
	 */
	private void deviceOfflineHandler(String topic, String content) {
		Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
		String productKey = String.valueOf(json.get("productKey"));
		String deviceName = String.valueOf(json.get("deviceName"));
		String time = String.valueOf(json.get("time"));
		DeviceStateModel deviceStateModel = new DeviceStateModel();
		deviceStateModel.setProductKey(productKey);
		deviceStateModel.setDeviceName(deviceName);
		DeviceStateModel result = deviceStateService.getDeviceState(deviceStateModel);
		if(result != null) {
			Timestamp updateTime = result.getUpdateTime();
			Timestamp resultTime = new Timestamp(DateUtil.parseDate(time,"yyyy-MM-dd HH:mm:ss").getTime());
			if(updateTime == null || resultTime == null ||
					updateTime.before(resultTime)) {
				deviceStateModel.setState(DeviceStateEnum.OFF_LINE.getCode());
				deviceStateModel.setUpdateTime(resultTime);
				deviceStateService.updateDeviceState(deviceStateModel);
			}else {
				logger.info("-------本次设备状态更新时间:"+resultTime+",上次设备状态更新时间:\"+updateTime+\",不需要做状态更新--------------------");
			}
		}
	}

	/**
	 * [设备属性上报]
	 * 
	 * @param topic
	 * @param content
	 */
	private void devicePropertyPostHandler(String topic, String content) {
		/** 设备上报属性 */
		DictionarieModel dictionarieModel = new DictionarieModel();
		dictionarieModel.setDictionarieType("DeviceReportProperty");
		List<DictionarieModel> dictionarieModelList = dictionarieService.getDictionarieByType(dictionarieModel);
		List<String> propertyList = dictionarieModelList.stream()
				.map(dictionarieKey -> dictionarieModel.getDictionarieKey()).collect(Collectors.toList());

		Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
		String productKey = String.valueOf(json.get("productKey"));
		String deviceName = String.valueOf(json.get("deviceName"));
		String iotId = String.valueOf(json.get("iotId"));
		String items = String.valueOf(json.get("items"));
		Map<String, Object> itemsJSON = (Map<String, Object>) JSON.parse(items);
		for (Map.Entry<String, Object> entry : itemsJSON.entrySet()) {
			String key = entry.getKey();
			Object value = entry.getValue();
			if (dictionarieModelList != null && dictionarieModelList.size() > 0) {
				for (int i = 0; i < dictionarieModelList.size(); i++) {
					DictionarieModel info = dictionarieModelList.get(i);
					if (info.getDictionarieKey().contains(key)) {
						Map<String, Object> propertyJSON = (Map<String, Object>) JSON.parse(value.toString());
						String time = propertyJSON.get("time").toString();
						String propertyValue = propertyJSON.get("value").toString();
						PropertyReportFlowModel propertyReportFlowModel = new PropertyReportFlowModel();
						propertyReportFlowModel.setId(UUID.randomUUID().toString().replace("-", ""));
						propertyReportFlowModel.setProductKey(productKey);
						propertyReportFlowModel.setDeviceName(deviceName);
						propertyReportFlowModel.setIotId(iotId);
						propertyReportFlowModel.setPropertyKey(info.getDictionarieKey());
						propertyReportFlowModel.setPropertyName(info.getDictionarieDescribe());
						propertyReportFlowModel.setPropertyValue(propertyValue);
						propertyReportFlowModel.setPropertyType(ReportPropertyTypeEnum.DEVICE.getCode());
						propertyReportFlowModel.setReportTime(new Timestamp(Long.parseLong(time)));
						propertyReportFlowModel.setCreateTime(new Timestamp(new Date().getTime()));
						propertyReportFlowService.insertPropertyReportFlow(propertyReportFlowModel);
						propertyReportService.insertPropertyReport(new PropertyReportModel(propertyReportFlowModel));
					}
				}
			}
		}
	}

	/**
	 * [自定义消息处理]
	 * 
	 * @param topic
	 * @param content
	 */
	public void customTopicHandler(String topic, String content) {

		if (!StringUtils.isNullOrEmpty(content)) {
			String requestId = UUID.randomUUID().toString().replace("-", "");
			Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
			String key = String.valueOf(json.get("key"));
			if (lowerData(key)) {
				// 下位机业务数据上报
				lowerDataHandler(topic, content, requestId);
			} else if (lowerWarn(key)) {
				// 下位机告警数据上报
				lowerWarnHandler(topic, content, requestId);
			} else if (dtuData(key)) {
				// DTU数据上报
				dtuDataHandler(topic, content, requestId);
			} else if (dtuConfig(key)) {
				// DTU配置反馈
				dtuConfigHandler(topic, content);
			} else if (plcModel(key)) {
				// 下位机型号
				plcModelHandler(topic, content, requestId);
			} else if (powerData(key)) {
				// 下位机业务数据上报
				powerDataHandler(topic, content, requestId);
			}
		}
	}

	/**
	 * [自定义消息处理]
	 * 
	 * @param topic
	 * @param content
	 */
	public void customTopicHandler(String topic, String content, String requestId) {
		
		if (!StringUtils.isNullOrEmpty(content)) {
			Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
			String key = String.valueOf(json.get("key"));
			boolean flag = checkDevice(json);
			if(flag) {
				if (lowerData(key)) {
					// 下位机业务数据上报
					lowerDataHandler(topic, content, requestId);
				}
				if (lowerWarn(key)) {
					// 位机告警数据上报
					lowerWarnHandler(topic, content, requestId);
				}
				if (dtuData(key)) {
					// DTU数据上报
					dtuDataHandler(topic, content, requestId);
				}
				if (plcModel(key)) {
					// 下位机型号上报
					plcModelHandler(topic, content, requestId);
				}

			}
		}
	}

	/**
	 * [下位机业务数据上报]
	 * 
	 * @param key
	 * @return
	 */
	private boolean lowerData(String key) {
		return CustomTopicEnum.LOWER_DATA.getCode().equals(key) || CustomTopicEnum.D_LOWER_DATA.getCode().equals(key)
				|| CustomTopicEnum.D_ALL_DATA.getCode().equals(key);
	}

	/**
	 * [电表数据上报]
	 *
	 * @param key
	 * @return
	 */
	private boolean powerData(String key) {
		return CustomTopicEnum.POWER_DATA.getCode().equals(key) || CustomTopicEnum.D_POWER_DATA.getCode().equals(key)
				|| CustomTopicEnum.D_ALL_DATA.getCode().equals(key);
	}

	/**
	 * [下位机告警数据上报]
	 * 
	 * @param key
	 * @return
	 */
	private boolean lowerWarn(String key) {
		return CustomTopicEnum.LOWER_WARN.getCode().equals(key) || CustomTopicEnum.D_LOWER_WARN.getCode().equals(key)
				|| CustomTopicEnum.D_ALL_DATA.getCode().equals(key);
	}

	/**
	 * [DTU数据上报]
	 * 
	 * @param key
	 * @return
	 */
	private boolean dtuData(String key) {
		return CustomTopicEnum.DEV_DATA.getCode().equals(key) || CustomTopicEnum.D_DEV_DATA.getCode().equals(key)
				|| CustomTopicEnum.D_ALL_DATA.getCode().equals(key);
	}
	
	/**
	 * [下位机型号]
	 * @param key
	 * @return
	 */
	private boolean plcModel(String key) {
		return CustomTopicEnum.LOWER_DMODEL.getCode().equals(key) || CustomTopicEnum.D_LOWER_DMODEL.getCode().equals(key)
				|| CustomTopicEnum.D_ALL_DATA.getCode().equals(key);
	}

	/**
	 * [DTU升级反馈]
	 * 
	 * @param key
	 * @return
	 */
	private boolean dtuOta(String topic) {
		boolean flag = false;
		if (topic.lastIndexOf(aliyunConfig.upgradeTopic) >= 0) {
			flag = true;
		}
		return flag;
	}

	/**
	 * [DTU配置反馈]
	 * 
	 * @param key
	 * @return
	 */
	private boolean dtuConfig(String key) {
		return CustomTopicEnum.DEV_CONFIG.getCode().equals(key);
	}

	/**
	 * [下位机业务数据上报]
	 * 
	 * @param topic
	 * @param content
	 */
	private void lowerDataHandler(String topic, String content) {
		lowerDataHandler(topic, content, null);
	}

	/**
	 * [下位机业务数据上报]
	 * 
	 * @param topic
	 * @param content
	 */
	private void lowerDataHandler(String topic, String content, String requestId) {

		/** 需要处理的下位机上报属性 */
		DictionarieModel dictionarieModel = new DictionarieModel();
		dictionarieModel.setDictionarieType("PLCReportProperty");
		List<DictionarieModel> dictionarieModelList = dictionarieService.getDictionarieByType(dictionarieModel);

		Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
		String productKey = String.valueOf(json.get("productKey"));
		String deviceName = String.valueOf(json.get("devKey"));
		if (!StringUtils.isNullOrEmpty(productKey) && !StringUtils.isNullOrEmpty(deviceName)) {
			DeviceStateModel deviceStateModel = new DeviceStateModel();
			deviceStateModel.setDeviceName(deviceName);
			deviceStateModel.setProductKey(productKey);
			DeviceStateModel result = deviceStateService.getDeviceState(deviceStateModel);
			if (result != null) {
				deviceStateModel.setReportTime(new Timestamp(new Date().getTime()));
				deviceStateService.updateDeviceState(deviceStateModel);
			}
			String iotId = "";
			for (int i = 0; i < dictionarieModelList.size(); i++) {
				DictionarieModel info = dictionarieModelList.get(i);
				String dictionarieKey = info.getDictionarieKey();
				if (json.get(dictionarieKey) != null) {
					if (result != null) {
						iotId = result.getIotId();
					}
					Object date = json.get("date");
					String time = "";
					if (date != null) {
						time = String.valueOf(date);
					}
					String propertyValue = json.get(dictionarieKey).toString();
					PropertyReportFlowModel propertyReportFlowModel = new PropertyReportFlowModel();
					propertyReportFlowModel.setId(UUID.randomUUID().toString().replace("-", ""));
					propertyReportFlowModel.setProductKey(productKey);
					propertyReportFlowModel.setDeviceName(deviceName);
					propertyReportFlowModel.setIotId(iotId);
					propertyReportFlowModel.setPropertyKey(info.getDictionarieKey());
					propertyReportFlowModel.setPropertyName(info.getDictionarieDescribe());
					propertyReportFlowModel.setPropertyValue(propertyValue);
					propertyReportFlowModel.setPropertyType(ReportPropertyTypeEnum.LOWER_MACHINE.getCode());
					propertyReportFlowModel.setRequestId(requestId);
					if (!StringUtils.isNullOrEmpty(time)) {
						logger.info("----------time:"+time+"-----------");
						Date recordDate = new Date(Long.parseLong(time));
						Date paresDate = DateUtil.getDate(recordDate, "yyyy-MM-dd HH:mm:ss");
						propertyReportFlowModel.setReportTime(new Timestamp(paresDate.getTime()));
					}
					propertyReportFlowModel.setCreateTime(new Timestamp(new Date().getTime()));
					propertyReportFlowService.insertPropertyReportFlow(propertyReportFlowModel);
					propertyReportService.insertPropertyReport(new PropertyReportModel(propertyReportFlowModel));
				}
			}
		}
	}

	/**
	 * [下位机告警数据上报]
	 * 
	 * @param topic
	 * @param content
	 */
	private void lowerWarnHandler(String topic, String content) {
		lowerWarnHandler(topic, content, null);
	}
	
	/**
	 * [下位机告警数据上报]
	 * 
	 * @param topic
	 * @param content
	 */
	private void lowerWarnHandler(String topic, String content, String requestId) {
		Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
		String productKey = String.valueOf(json.get("productKey"));
		String deviceName = String.valueOf(json.get("devKey"));
		String warn = String.valueOf(json.get("warn"));
		String date = String.valueOf(json.get("date"));
		String dpno = String.valueOf(json.get("dpno"));
		dpno = json.get("dpno") == null ? "0" : dpno;
 		char[] warnArray = getWarnArray(warn);
		
		if (!StringUtils.isNullOrEmpty(productKey) && !StringUtils.isNullOrEmpty(deviceName)) {
			DeviceStateModel deviceStateModel = new DeviceStateModel();
			deviceStateModel.setDeviceName(deviceName);
			deviceStateModel.setProductKey(productKey);
			deviceStateModel.setReportTime(new Timestamp(new Date().getTime()));
			deviceStateService.updateDeviceState(deviceStateModel);
			
			for (int i = 0; i < warnArray.length; i++) {
				PLCWarnReportModel plcWarnReportModel = new PLCWarnReportModel();
				plcWarnReportModel.setProductKey(productKey);
				plcWarnReportModel.setDeviceName(deviceName);
				plcWarnReportModel.setDpno(dpno);
				plcWarnReportModel.setWtype(String.valueOf(i));
				plcWarnReportModel.setVal(String.valueOf(warnArray[i]));
				plcWarnReportModel.setStatus("0");
				plcWarnReportModel.setCreateTime(new Timestamp(Long.parseLong(date)));
				plcWarnReportModel.setRequestId(requestId);
				plcWarnReportService.insertPLCWarnReport(plcWarnReportModel);
			}
		}
		
		List<PLCWarnReportModel> plcWarnReportList = plcWarnReportService.
				getPLCWarnInfo(productKey, deviceName, dpno, requestId);
		if(plcWarnReportList != null && plcWarnReportList.size() > 0) {
			for (int i = 0; i < plcWarnReportList.size(); i++) {
				PLCWarnReportModel plcWarnReportModel = plcWarnReportList.get(i);
				PLCWarnFlowModel plcWarnFlowModel = new PLCWarnFlowModel();
				plcWarnFlowModel.setDpno(dpno);
				plcWarnFlowModel.setProductKey(productKey);
				plcWarnFlowModel.setDeviceName(deviceName);
				plcWarnFlowModel.setWtype(plcWarnReportModel.getWtype());
				plcWarnFlowModel.setVal(plcWarnReportModel.getVal());
				plcWarnFlowModel.setStatus("0");
				plcWarnFlowModel.setCreateTime(new Timestamp(Long.parseLong(date)));
				plcWarnFlowModel.setRequestId(requestId);
				plcWarnFlowService.insertPLCWarn(plcWarnFlowModel);
				plcWarnService.insertPLCWarn(new PLCWarnModel(plcWarnFlowModel));
			}
		}
	}

//	/**
//	 * [下位机告警数据上报]
//	 * 
//	 * @param topic
//	 * @param content
//	 */
//	private void lowerWarnHandler(String topic, String content, String requestId) {
//		Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
//		String productKey = String.valueOf(json.get("productKey"));
//		String deviceName = String.valueOf(json.get("devKey"));
//		String warn = String.valueOf(json.get("warn"));
//		String date = String.valueOf(json.get("date"));
//		String[] warnArray = getWarnArray(warn);
//		
//		if (!StringUtils.isNullOrEmpty(productKey) && !StringUtils.isNullOrEmpty(deviceName)) {
//			DeviceStateModel deviceStateModel = new DeviceStateModel();
//			deviceStateModel.setDeviceName(deviceName);
//			deviceStateModel.setProductKey(productKey);
//			deviceStateModel.setReportTime(new Timestamp(new Date().getTime()));
//			deviceStateService.updateDeviceState(deviceStateModel);
//			
//			for (int i = 0; i <= warnArray.length; i++) {
//				PLCWarnFlowModel plcWarnFlowModel = new PLCWarnFlowModel();
//				plcWarnFlowModel.setProductKey(productKey);
//				plcWarnFlowModel.setDeviceName(deviceName);
//				plcWarnFlowModel.setWtype(String.valueOf(i));
//				plcWarnFlowModel.setVal(warnArray[i - 1]);
//				plcWarnFlowModel.setStatus("0");
//				plcWarnFlowModel.setCreateTime(new Timestamp(Long.parseLong(date)));
//				plcWarnFlowModel.setRequestId(requestId);
//				plcWarnFlowService.insertPLCWarn(plcWarnFlowModel);
//				plcWarnService.insertPLCWarn(new PLCWarnModel(plcWarnFlowModel));
//			}
//		}
//	}

	/**
	 * [DTU数据上报]
	 * 
	 * @param topic
	 * @param content
	 */
	private void dtuDataHandler(String topic, String content) {
		dtuDataHandler(topic, content, null);
	}

	/**
	 * [DTU数据上报]
	 * 
	 * @param topic
	 * @param content
	 */
	private void dtuDataHandler(String topic, String content, String requestId) {
		/** 需要处理的设备上报属性 */
		DictionarieModel dictionarieModel = new DictionarieModel();
		dictionarieModel.setDictionarieType("DeviceReportProperty");
		List<DictionarieModel> dictionarieModelList = dictionarieService.getDictionarieByType(dictionarieModel);

		Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
		String productKey = String.valueOf(json.get("productKey"));
		String deviceName = String.valueOf(json.get("devKey"));
		if (!StringUtils.isNullOrEmpty(productKey) && !StringUtils.isNullOrEmpty(deviceName)) {
			DeviceStateModel deviceStateModel = new DeviceStateModel();
			deviceStateModel.setDeviceName(deviceName);
			deviceStateModel.setProductKey(productKey);
			DeviceStateModel result = deviceStateService.getDeviceState(deviceStateModel);

			if(result != null) {
				deviceStateModel.setReportTime(new Timestamp(new Date().getTime()));
				deviceStateService.updateDeviceState(deviceStateModel);
			}
			String iotId = "";
			for (int i = 0; i < dictionarieModelList.size(); i++) {
				DictionarieModel info = dictionarieModelList.get(i);
				String dictionarieKey = info.getDictionarieKey();
				if (json.get(dictionarieKey) != null) {
					if (result != null) {
						iotId = result.getIotId();
					}
					String time = json.get("date").toString();
					String propertyValue = json.get(dictionarieKey).toString();
					PropertyReportFlowModel propertyReportFlowModel = new PropertyReportFlowModel();
					propertyReportFlowModel.setId(UUID.randomUUID().toString().replace("-", ""));
					propertyReportFlowModel.setProductKey(productKey);
					propertyReportFlowModel.setDeviceName(deviceName);
					propertyReportFlowModel.setIotId(iotId);
					propertyReportFlowModel.setPropertyKey(info.getDictionarieKey());
					propertyReportFlowModel.setPropertyName(info.getDictionarieDescribe());
					propertyReportFlowModel.setPropertyValue(propertyValue);
					propertyReportFlowModel.setRequestId(requestId);
					propertyReportFlowModel.setPropertyType(ReportPropertyTypeEnum.DEVICE.getCode());
					if (!StringUtils.isNullOrEmpty(time)) {
						propertyReportFlowModel.setReportTime(new Timestamp(Long.parseLong(time)));
					}
					propertyReportFlowModel.setCreateTime(new Timestamp(new Date().getTime()));
					propertyReportFlowService.insertPropertyReportFlow(propertyReportFlowModel);
					propertyReportService.insertPropertyReport(new PropertyReportModel(propertyReportFlowModel));
				}
			}
		}
	}

	/**
	 * [DTU升级反馈]
	 * 
	 * @param topic
	 * @param content
	 */
	private void dtuOtaHandler(String topic, String content) {
		Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
		String productKey = String.valueOf(json.get("productKey"));
		String deviceName = String.valueOf(json.get("deviceName"));
		String jobId = String.valueOf(json.get("jobId"));
		String version = String.valueOf(json.get("destVersion"));
		String date = String.valueOf(json.get("messageCreateTime"));
		String success = String.valueOf(json.get("status"));

		if (!StringUtils.isNullOrEmpty(productKey) && !StringUtils.isNullOrEmpty(deviceName)) {
			DeviceUpgradeModel deviceUpgradeModel = new DeviceUpgradeModel();
			deviceUpgradeModel.setProductKey(productKey);
			deviceUpgradeModel.setDeviceName(deviceName);
			deviceUpgradeModel.setJobId(jobId);
			deviceUpgradeModel.setVersion(version);
			deviceUpgradeModel.setResponseTime(new Timestamp(Long.parseLong(date)));
			deviceUpgradeModel.setStatus("SUCCEEDED".equals(success) ? "1" : "2");
			deviceUpgradeService.updateDeviceUpgradeStatus(deviceUpgradeModel);

			DeviceUpgradeFlowModel deviceUpgradeFlowModel = new DeviceUpgradeFlowModel();
			deviceUpgradeFlowModel.setProductKey(productKey);
			deviceUpgradeFlowModel.setDeviceName(deviceName);
			deviceUpgradeFlowModel.setJobId(jobId);
			deviceUpgradeFlowModel.setVersion(version);
			deviceUpgradeFlowModel.setResponseTime(new Timestamp(Long.parseLong(date)));
			deviceUpgradeFlowModel.setStatus("true".equals(success) ? "1" : "2");
			deviceUpgradeFlowService.updateDeviceUpgradeStatus(deviceUpgradeFlowModel);
		}
	}

	/**
	 * [DTU配置反馈]
	 * 
	 * @param topic
	 * @param content
	 */
	private void dtuConfigHandler(String topic, String content) {
		Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
		String productKey = String.valueOf(json.get("productKey"));
		String deviceName = String.valueOf(json.get("devKey"));
		String messageId = String.valueOf(json.get("messageId"));
		String version = String.valueOf(json.get("version"));
		String date = String.valueOf(json.get("date"));
		String success = String.valueOf(json.get("success"));
		if (!StringUtils.isNullOrEmpty(productKey) && !StringUtils.isNullOrEmpty(deviceName)) {
			PropertiesSetModel propertiesSetModel = new PropertiesSetModel();
			propertiesSetModel.setProductKey(productKey);
			propertiesSetModel.setDeviceName(deviceName);
			propertiesSetModel.setMessageId(messageId);
			propertiesSetModel.setVersion(version);
			propertiesSetModel.setResponseTime(new Timestamp(Long.parseLong(date)));
			propertiesSetModel.setStatus("true".equals(success) ? "1" : "2");
			propertiesSetService.updatePropertiesSetStatus(propertiesSetModel);

			PropertiesSetFlowModel propertiesSetFlowModel = new PropertiesSetFlowModel();
			propertiesSetFlowModel.setProductKey(productKey);
			propertiesSetFlowModel.setDeviceName(deviceName);
			propertiesSetFlowModel.setMessageId(messageId);
			propertiesSetFlowModel.setVersion(version);
			propertiesSetFlowModel.setResponseTime(new Timestamp(Long.parseLong(date)));
			propertiesSetFlowModel.setStatus("true".equals(success) ? "1" : "2");
			propertiesSetFlowService.updatePropertiesSetStatus(propertiesSetFlowModel);
		}
	}
	
	/**
	 * [下位机型号数据上报]
	 * 
	 * @param topic
	 * @param content
	 */
	private void plcModelHandler(String topic, String content) {
		plcModelHandler(topic, content, null);
	}

	/**
	 * [下位机型号数据上报]
	 * 
	 * @param topic
	 * @param content
	 */
	private void plcModelHandler(String topic, String content, String requestId) {
		Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
		String productKey = String.valueOf(json.get("productKey"));
		String deviceName = String.valueOf(json.get("devKey"));
		String dpno = String.valueOf(json.get("dpno"));
		String plcCode = String.valueOf(json.get("version"));
		dpno = json.get("dpno") == null ? "0" : dpno;
		String date = String.valueOf(json.get("date"));
		
		if (!StringUtils.isNullOrEmpty(productKey) && !StringUtils.isNullOrEmpty(deviceName)) {
			DeviceStateModel deviceStateModel = new DeviceStateModel();
			deviceStateModel.setDeviceName(deviceName);
			deviceStateModel.setProductKey(productKey);
			deviceStateModel.setReportTime(new Timestamp(new Date().getTime()));
			deviceStateService.updateDeviceState(deviceStateModel);
			
			PLCModelFlow plcModelFlow = new PLCModelFlow();
			plcModelFlow.setProductKey(productKey);
			plcModelFlow.setDeviceName(deviceName);
			plcModelFlow.setPlcCode(plcCode);
			plcModelFlow.setDpno(dpno);
			plcModelFlow.setRequestId(requestId);
			plcModelFlow.setReportTime(new Timestamp(Long.parseLong(date)));
			plcModelFlowService.insertPLCModel(plcModelFlow);
			devicePLCService.insertDevicePLC(new DevicePLC(plcModelFlow));
			
		}
	}

	/**
	 * [电表数据上报]
	 *
	 * @param topic
	 * @param content
	 */
	private void powerDataHandler(String topic, String content) {
		powerDataHandler(topic, content, null);
	}

	/**
	 * [电表数据上报]
	 *
	 * @param topic
	 * @param content
	 */
	private void powerDataHandler(String topic, String content, String requestId) {

		/** 需要处理的下位机上报属性 */
		DictionarieModel dictionarieModel = new DictionarieModel();
		dictionarieModel.setDictionarieType("PowerReportProperty");
		List<DictionarieModel> dictionarieModelList = dictionarieService.getDictionarieByType(dictionarieModel);

		Map<String, Object> json = (Map<String, Object>) JSON.parse(content);
		String productKey = String.valueOf(json.get("productKey"));
		String deviceName = String.valueOf(json.get("devKey"));
		if (!StringUtils.isNullOrEmpty(productKey) && !StringUtils.isNullOrEmpty(deviceName)) {
			DeviceStateModel deviceStateModel = new DeviceStateModel();
			deviceStateModel.setDeviceName(deviceName);
			deviceStateModel.setProductKey(productKey);
			DeviceStateModel result = deviceStateService.getDeviceState(deviceStateModel);
			if (result != null) {
				deviceStateModel.setReportTime(new Timestamp(new Date().getTime()));
				deviceStateService.updateDeviceState(deviceStateModel);
			}
			String iotId = "";
			for (int i = 0; i < dictionarieModelList.size(); i++) {
				DictionarieModel info = dictionarieModelList.get(i);
				String dictionarieKey = info.getDictionarieKey();
				if (json.get(dictionarieKey) != null) {
					if (result != null) {
						iotId = result.getIotId();
					}
					Object date = json.get("date");
					String time = "";
					if (date != null) {
						time = String.valueOf(date);
					}
					String propertyValue = json.get(dictionarieKey).toString();
					PropertyReportFlowModel propertyReportFlowModel = new PropertyReportFlowModel();
					propertyReportFlowModel.setId(UUID.randomUUID().toString().replace("-", ""));
					propertyReportFlowModel.setProductKey(productKey);
					propertyReportFlowModel.setDeviceName(deviceName);
					propertyReportFlowModel.setIotId(iotId);
					propertyReportFlowModel.setPropertyKey(info.getDictionarieKey());
					propertyReportFlowModel.setPropertyName(info.getDictionarieDescribe());
					propertyReportFlowModel.setPropertyValue(propertyValue);
					propertyReportFlowModel.setPropertyType(ReportPropertyTypeEnum.LOWER_POWER.getCode());
					propertyReportFlowModel.setRequestId(requestId);
					if (!StringUtils.isNullOrEmpty(time)) {
						logger.info("----------time:"+time+"-----------");
						Date recordDate = new Date(Long.parseLong(time));
						Date paresDate = DateUtil.getDate(recordDate, "yyyy-MM-dd HH:mm:ss");
						propertyReportFlowModel.setReportTime(new Timestamp(paresDate.getTime()));
					}
					propertyReportFlowModel.setCreateTime(new Timestamp(new Date().getTime()));
					propertyReportFlowService.insertPropertyReportFlow(propertyReportFlowModel);
					propertyReportService.insertPropertyReport(new PropertyReportModel(propertyReportFlowModel));
				}
			}
		}
	}

	public static char[] getWarnArray(String val) {
		char[] warnArray = Calculator.toBinaryCharArr(val);
		return warnArray;
	}
	
	public static void main(String[]args) {
		System.out.println(getWarnArray("2048"));
	}
	

	public String[] getWarnArray(String val, int digit) {
		int value = Integer.parseInt(val);
		String twoDecimal = binary2decimal(value, digit);
		String[] warnArray = new String[digit];
		for (int i = 0; i < twoDecimal.length(); i++) {
			warnArray[i] = twoDecimal.substring(digit-1 - i, digit - i);
		}
		return warnArray;
	}

	public String binary2decimal(int decNum, int digit) {
		String binStr = "";
		for (int i = digit - 1; i >= 0; i--) {
			binStr += (decNum >> i) & 1;
		}
		return binStr;
	}
	
	/**
	 * [判断设备是否存在]
	 * @param json
	 * @return
	 */
	public boolean checkDevice(Map<String, Object> json) {
		// 产品key
		String productKey = json.get("productKey") == null ? "" : String.valueOf(json.get("productKey"));
		// 设备名称
		String deviceName = json.get("deviceName") == null ? "" : String.valueOf(json.get("deviceName"));
		// 设备名称
		String devKey = json.get("devKey") == null ? "" : String.valueOf(json.get("devKey"));
		if (!StringUtils.isNullOrEmpty(productKey) 
				&& (!StringUtils.isNullOrEmpty(deviceName) || !StringUtils.isNullOrEmpty(devKey))) {
			deviceName = !StringUtils.isNullOrEmpty(deviceName) ? deviceName : devKey;
			DeviceStateModel deviceStateModel = new DeviceStateModel();
			deviceStateModel.setProductKey(productKey);
			deviceStateModel.setDeviceName(deviceName);
			DeviceStateModel deviceInfo = deviceStateService.getDeviceState(deviceStateModel);
			if(deviceInfo == null) {
				return false;
			}
		} else {
			return false;
		}
		return true;
	}
}
